Import library

library(tidyverse)
library(ggplot2)
library(gridExtra)

# knitr::opts_chunk$set(fig.height=15) 

# library(usethis) 
# usethis::edit_r_environ()

Read file


# real file name
df = read.csv('../dataset/cleaned/cleaned_dataset.csv')


# just for testing

# df = read.csv('../dataset/cleaned/sample_cleaned_dataset.csv')

# print(names(df))

head(df, 5)

Completion time by assignment_gs_correct_count, assignment_gs_count, assignment_price, microtasks_count.

Each plot is categorized by assignment_status, device_category, assignment_type


prepare.df.by.category = function(cat){
  
  data.by.cat = df %>% select('assignment_gs_correct_count',  'assignment_gs_count', 'assignment_price', 'microtasks_count', 'completion.time.in.minutes', cat)
  
  data.by.cat = data.by.cat %>% 
  pivot_longer(cols=c('assignment_gs_correct_count',  'assignment_gs_count', 'assignment_price', 'microtasks_count'), names_to = 'parameter')
  
  return(data.by.cat)
}

df2 = prepare.df.by.category('assignment_status')
Note: Using an external vector in selections is ambiguous.
ℹ Use `all_of(cat)` instead of `cat` to silence this message.
ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This message is displayed once per session.
plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_status)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 5),
    axis.title.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('device_category')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=device_category)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by device type') + 
  theme(
    strip.text = element_text(size = 5),
    axis.title.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt



df2 = prepare.df.by.category('assignment_type')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_type)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment type') + 
  theme(
    strip.text = element_text(size = 5),
    axis.title.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('project_instruction_language')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=project_instruction_language)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by instruction language') + 
  theme(
    strip.text = element_text(size = 5),
    axis.title.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt

Completion time by project attribute (has_audio, has_button, has_checkbox_input, has_externalHtml, has_fileAudio_input, has_fileImg_input, has_fileVideo_input, has_file_input, has_iframe, has_image, has_radio_input, has_sbs, has_select_input, has_sourcesRecorder_input, has_string_input, has_suggest_input, has_textarea_input, has_video)

Each plot is categorized by assignment_status, device_category, assignment_type


prepare.df.by.category = function(cat){
  
  data.by.cat = df %>% select(project_has_audio, project_has_externalHtml, project_has_fileAudio_input, project_has_fileImg_input, project_has_file_input, project_has_iframe, project_has_sbs, project_has_select_input, project_has_sourcesRecorder_input, project_has_suggest_input, project_has_textarea_input, project_has_video, cat, completion.time.in.minutes)
  
  data.by.cat = data.by.cat %>% 
  pivot_longer(cols=c('project_has_audio', 'project_has_externalHtml', 'project_has_fileAudio_input', 'project_has_fileImg_input', 'project_has_file_input', 'project_has_iframe', 'project_has_sbs', 'project_has_select_input', 'project_has_sourcesRecorder_input', 'project_has_suggest_input', 'project_has_textarea_input', 'project_has_video'), names_to = 'parameter')
  
  return(data.by.cat)
}

df2 = prepare.df.by.category('assignment_status')

plt = df2 %>% ggplot(aes(x=factor(value), y=completion.time.in.minutes, color=assignment_status)) +
  geom_boxplot() +
  facet_wrap(vars(parameter), nrow=4, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 12),
    axis.text.x = element_text(size=15),
    axis.text.y = element_text(size = 15),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('device_category')

plt = df2 %>% ggplot(aes(x=factor(value), y=completion.time.in.minutes, color=device_category)) +
  geom_boxplot() +
  facet_wrap(vars(parameter), nrow=4, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 12),
    axis.text.x = element_text(size=15),
    axis.text.y = element_text(size = 15),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('assignment_type')

plt = df2 %>% ggplot(aes(x=factor(value), y=completion.time.in.minutes, color=assignment_type)) +
  geom_boxplot() +
  facet_wrap(vars(parameter), nrow=4, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 12),
    axis.text.x = element_text(size=15),
    axis.text.y = element_text(size = 15),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('project_instruction_language')
Note: Using an external vector in selections is ambiguous.
ℹ Use `all_of(cat)` instead of `cat` to silence this message.
ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This message is displayed once per session.
plt = df2 %>% ggplot(aes(x=factor(value), y=completion.time.in.minutes, color=project_instruction_language)) +
  geom_boxplot() +
  facet_wrap(vars(parameter), nrow=4, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 12),
    axis.text.x = element_text(size=15),
    axis.text.y = element_text(size = 15),
    legend.position = 'bottom'
  )

plt

Completion time by project attribute (instruction_FK, instruction_language, instruction_len, instruction_wordCount, required_fields, spec_length)

Each plot is categorized by assignment_status, device_category, assignment_type, instruction_language

prepare.df.by.category = function(cat){
  
  # data.by.cat = df %>% select(project_instruction_FK, project_instruction_len, project_instruction_wordCount, project_required_fields, project_spec_length, project_has_button,  project_has_checkbox_input, project_has_image, project_has_radio_input, project_has_string_input, completion.time.in.minutes, cat)
  data.by.cat = df %>% select(project_instruction_FK, project_instruction_len, project_instruction_wordCount, project_required_fields, project_spec_length, completion.time.in.minutes, cat)
  
  data.by.cat = data.by.cat %>% 
  # pivot_longer(cols=c('project_instruction_FK', 'project_instruction_len', 'project_instruction_wordCount', 'project_required_fields', 'project_spec_length', 'project_has_button',  'project_has_checkbox_input', 'project_has_image', 'project_has_radio_input', 'project_has_string_input'), names_to = 'parameter')
    pivot_longer(cols=c('project_instruction_FK', 'project_instruction_len', 'project_instruction_wordCount', 'project_required_fields', 'project_spec_length'), names_to = 'parameter')
  
  return(data.by.cat)
}

df2 = prepare.df.by.category('assignment_status')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_status)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt

df2 = prepare.df.by.category('device_category')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=device_category)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by device type') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('assignment_type')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_type)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment type') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('project_instruction_language')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=project_instruction_language)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by instruction language') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt

Completion time by project attribute (instruction_FK, instruction_language, instruction_len, instruction_wordCount, required_fields, spec_length, project_has_button, project_has_checkbox_input, project_has_image, project_has_radio_input, project_has_string_input)

Each plot is categorized by assignment_status, device_category, assignment_type, instruction_language

prepare.df.by.category = function(cat){
  
  # data.by.cat = df %>% select(project_instruction_FK, project_instruction_len, project_instruction_wordCount, project_required_fields, project_spec_length, project_has_button,  project_has_checkbox_input, project_has_image, project_has_radio_input, project_has_string_input, completion.time.in.minutes, cat)
  data.by.cat = df %>% select(project_has_button,  project_has_checkbox_input, project_has_image, project_has_radio_input, project_has_string_input, completion.time.in.minutes, cat)
  
  data.by.cat = data.by.cat %>% 
  # pivot_longer(cols=c('project_instruction_FK', 'project_instruction_len', 'project_instruction_wordCount', 'project_required_fields', 'project_spec_length', 'project_has_button',  'project_has_checkbox_input', 'project_has_image', 'project_has_radio_input', 'project_has_string_input'), names_to = 'parameter')
    pivot_longer(cols=c('project_has_button',  'project_has_checkbox_input', 'project_has_image', 'project_has_radio_input', 'project_has_string_input'), names_to = 'parameter')
  
  return(data.by.cat)
}

df2 = prepare.df.by.category('assignment_status')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_status)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment status') + 
  theme(
    strip.text = element_text(size = 10),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt

df2 = prepare.df.by.category('device_category')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=device_category)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by device type') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('assignment_type')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=assignment_type)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by assignment type') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt


df2 = prepare.df.by.category('project_instruction_language')

plt = df2 %>% ggplot(aes(x=value, y=completion.time.in.minutes, color=project_instruction_language)) +
  geom_point(alpha = 0.5) +
  facet_wrap(vars(parameter), nrow=1, scales = "free_x") +
  xlab('') + ylab('completion time (in minute)') + 
  ggtitle('plot by instruction language') + 
  theme(
    strip.text = element_text(size = 8),
    axis.text.x = element_text(size=8, angle = 30),
    axis.text.y = element_text(size = 8),
    legend.position = 'bottom'
  )

plt

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCmZpZ19oZWlnaHQ6IDIwMAotLS0KCjxoMj5JbXBvcnQgbGlicmFyeTwvaDI+CgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCgojIGtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcuaGVpZ2h0PTE1KSAKCiMgbGlicmFyeSh1c2V0aGlzKSAKIyB1c2V0aGlzOjplZGl0X3JfZW52aXJvbigpCmBgYAoKPGgyPlJlYWQgZmlsZTwvaDI+CgpgYGB7cn0KCiMgcmVhbCBmaWxlIG5hbWUKZGYgPSByZWFkLmNzdignLi4vZGF0YXNldC9jbGVhbmVkL2NsZWFuZWRfZGF0YXNldC5jc3YnKQoKCiMganVzdCBmb3IgdGVzdGluZwoKIyBkZiA9IHJlYWQuY3N2KCcuLi9kYXRhc2V0L2NsZWFuZWQvc2FtcGxlX2NsZWFuZWRfZGF0YXNldC5jc3YnKQoKIyBwcmludChuYW1lcyhkZikpCgpoZWFkKGRmLCA1KQpgYGAKCgoKQ29tcGxldGlvbiB0aW1lIGJ5IGFzc2lnbm1lbnRfZ3NfY29ycmVjdF9jb3VudCwgIGFzc2lnbm1lbnRfZ3NfY291bnQsIGFzc2lnbm1lbnRfcHJpY2UsIG1pY3JvdGFza3NfY291bnQuCgpFYWNoIHBsb3QgaXMgY2F0ZWdvcml6ZWQgYnkgYXNzaWdubWVudF9zdGF0dXMsIGRldmljZV9jYXRlZ29yeSwgYXNzaWdubWVudF90eXBlCgpgYGB7cn0KCnByZXBhcmUuZGYuYnkuY2F0ZWdvcnkgPSBmdW5jdGlvbihjYXQpewogIAogIGRhdGEuYnkuY2F0ID0gZGYgJT4lIHNlbGVjdCgnYXNzaWdubWVudF9nc19jb3JyZWN0X2NvdW50JywgICdhc3NpZ25tZW50X2dzX2NvdW50JywgJ2Fzc2lnbm1lbnRfcHJpY2UnLCAnbWljcm90YXNrc19jb3VudCcsICdjb21wbGV0aW9uLnRpbWUuaW4ubWludXRlcycsIGNhdCkKICAKICBkYXRhLmJ5LmNhdCA9IGRhdGEuYnkuY2F0ICU+JSAKICBwaXZvdF9sb25nZXIoY29scz1jKCdhc3NpZ25tZW50X2dzX2NvcnJlY3RfY291bnQnLCAgJ2Fzc2lnbm1lbnRfZ3NfY291bnQnLCAnYXNzaWdubWVudF9wcmljZScsICdtaWNyb3Rhc2tzX2NvdW50JyksIG5hbWVzX3RvID0gJ3BhcmFtZXRlcicpCiAgCiAgcmV0dXJuKGRhdGEuYnkuY2F0KQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD01LjV9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdhc3NpZ25tZW50X3N0YXR1cycpCgpwbHQgPSBkZjIgJT4lIGdncGxvdChhZXMoeD12YWx1ZSwgeT1jb21wbGV0aW9uLnRpbWUuaW4ubWludXRlcywgY29sb3I9YXNzaWdubWVudF9zdGF0dXMpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCBzdGF0dXMnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKYGBge3IgZmlnLmhlaWdodD0zLjV9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdkZXZpY2VfY2F0ZWdvcnknKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWRldmljZV9jYXRlZ29yeSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZmFjZXRfd3JhcCh2YXJzKHBhcmFtZXRlciksIG5yb3c9MSwgc2NhbGVzID0gImZyZWVfeCIpICsKICB4bGFiKCcnKSArIHlsYWIoJ2NvbXBsZXRpb24gdGltZSAoaW4gbWludXRlKScpICsgCiAgZ2d0aXRsZSgncGxvdCBieSBkZXZpY2UgdHlwZScpICsgCiAgdGhlbWUoCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJwogICkKCnBsdApgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTN9CgoKZGYyID0gcHJlcGFyZS5kZi5ieS5jYXRlZ29yeSgnYXNzaWdubWVudF90eXBlJykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PXZhbHVlLCB5PWNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjb2xvcj1hc3NpZ25tZW50X3R5cGUpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCB0eXBlJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9M30KCmRmMiA9IHByZXBhcmUuZGYuYnkuY2F0ZWdvcnkoJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UnKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPXByb2plY3RfaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgaW5zdHJ1Y3Rpb24gbGFuZ3VhZ2UnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKQ29tcGxldGlvbiB0aW1lIGJ5IHByb2plY3QgYXR0cmlidXRlIChoYXNfYXVkaW8sIGhhc19idXR0b24sIGhhc19jaGVja2JveF9pbnB1dCwgaGFzX2V4dGVybmFsSHRtbCwgaGFzX2ZpbGVBdWRpb19pbnB1dCwgaGFzX2ZpbGVJbWdfaW5wdXQsIGhhc19maWxlVmlkZW9faW5wdXQsIGhhc19maWxlX2lucHV0LCBoYXNfaWZyYW1lLCBoYXNfaW1hZ2UsIGhhc19yYWRpb19pbnB1dCwgaGFzX3NicywgaGFzX3NlbGVjdF9pbnB1dCwgaGFzX3NvdXJjZXNSZWNvcmRlcl9pbnB1dCwgaGFzX3N0cmluZ19pbnB1dCwgaGFzX3N1Z2dlc3RfaW5wdXQsIGhhc190ZXh0YXJlYV9pbnB1dCwgaGFzX3ZpZGVvKQoKRWFjaCBwbG90IGlzIGNhdGVnb3JpemVkIGJ5IGFzc2lnbm1lbnRfc3RhdHVzLCBkZXZpY2VfY2F0ZWdvcnksIGFzc2lnbm1lbnRfdHlwZQoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9CgpwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5ID0gZnVuY3Rpb24oY2F0KXsKICAKICBkYXRhLmJ5LmNhdCA9IGRmICU+JSBzZWxlY3QocHJvamVjdF9oYXNfYXVkaW8sIHByb2plY3RfaGFzX2V4dGVybmFsSHRtbCwgcHJvamVjdF9oYXNfZmlsZUF1ZGlvX2lucHV0LCBwcm9qZWN0X2hhc19maWxlSW1nX2lucHV0LCBwcm9qZWN0X2hhc19maWxlX2lucHV0LCBwcm9qZWN0X2hhc19pZnJhbWUsIHByb2plY3RfaGFzX3NicywgcHJvamVjdF9oYXNfc2VsZWN0X2lucHV0LCBwcm9qZWN0X2hhc19zb3VyY2VzUmVjb3JkZXJfaW5wdXQsIHByb2plY3RfaGFzX3N1Z2dlc3RfaW5wdXQsIHByb2plY3RfaGFzX3RleHRhcmVhX2lucHV0LCBwcm9qZWN0X2hhc192aWRlbywgY2F0LCBjb21wbGV0aW9uLnRpbWUuaW4ubWludXRlcykKICAKICBkYXRhLmJ5LmNhdCA9IGRhdGEuYnkuY2F0ICU+JSAKICBwaXZvdF9sb25nZXIoY29scz1jKCdwcm9qZWN0X2hhc19hdWRpbycsICdwcm9qZWN0X2hhc19leHRlcm5hbEh0bWwnLCAncHJvamVjdF9oYXNfZmlsZUF1ZGlvX2lucHV0JywgJ3Byb2plY3RfaGFzX2ZpbGVJbWdfaW5wdXQnLCAncHJvamVjdF9oYXNfZmlsZV9pbnB1dCcsICdwcm9qZWN0X2hhc19pZnJhbWUnLCAncHJvamVjdF9oYXNfc2JzJywgJ3Byb2plY3RfaGFzX3NlbGVjdF9pbnB1dCcsICdwcm9qZWN0X2hhc19zb3VyY2VzUmVjb3JkZXJfaW5wdXQnLCAncHJvamVjdF9oYXNfc3VnZ2VzdF9pbnB1dCcsICdwcm9qZWN0X2hhc190ZXh0YXJlYV9pbnB1dCcsICdwcm9qZWN0X2hhc192aWRlbycpLCBuYW1lc190byA9ICdwYXJhbWV0ZXInKQogIAogIHJldHVybihkYXRhLmJ5LmNhdCkKfQoKYGBgCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OH0KCmRmMiA9IHByZXBhcmUuZGYuYnkuY2F0ZWdvcnkoJ2Fzc2lnbm1lbnRfc3RhdHVzJykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PWZhY3Rvcih2YWx1ZSksIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWFzc2lnbm1lbnRfc3RhdHVzKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBmYWNldF93cmFwKHZhcnMocGFyYW1ldGVyKSwgbnJvdz00LCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHhsYWIoJycpICsgeWxhYignY29tcGxldGlvbiB0aW1lIChpbiBtaW51dGUpJykgKyAKICBnZ3RpdGxlKCdwbG90IGJ5IGFzc2lnbm1lbnQgc3RhdHVzJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYAoKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04fQoKZGYyID0gcHJlcGFyZS5kZi5ieS5jYXRlZ29yeSgnZGV2aWNlX2NhdGVnb3J5JykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PWZhY3Rvcih2YWx1ZSksIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWRldmljZV9jYXRlZ29yeSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfd3JhcCh2YXJzKHBhcmFtZXRlciksIG5yb3c9NCwgc2NhbGVzID0gImZyZWVfeCIpICsKICB4bGFiKCcnKSArIHlsYWIoJ2NvbXBsZXRpb24gdGltZSAoaW4gbWludXRlKScpICsgCiAgZ2d0aXRsZSgncGxvdCBieSBhc3NpZ25tZW50IHN0YXR1cycpICsgCiAgdGhlbWUoCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJwogICkKCnBsdApgYGAKCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OH0KCmRmMiA9IHByZXBhcmUuZGYuYnkuY2F0ZWdvcnkoJ2Fzc2lnbm1lbnRfdHlwZScpCgpwbHQgPSBkZjIgJT4lIGdncGxvdChhZXMoeD1mYWN0b3IodmFsdWUpLCB5PWNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjb2xvcj1hc3NpZ25tZW50X3R5cGUpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTQsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCBzdGF0dXMnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdwcm9qZWN0X2luc3RydWN0aW9uX2xhbmd1YWdlJykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PWZhY3Rvcih2YWx1ZSksIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPXByb2plY3RfaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTQsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCBzdGF0dXMnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKQ29tcGxldGlvbiB0aW1lIGJ5IHByb2plY3QgYXR0cmlidXRlIChpbnN0cnVjdGlvbl9GSywgaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UsIGluc3RydWN0aW9uX2xlbiwgaW5zdHJ1Y3Rpb25fd29yZENvdW50LCByZXF1aXJlZF9maWVsZHMsIHNwZWNfbGVuZ3RoKQoKRWFjaCBwbG90IGlzIGNhdGVnb3JpemVkIGJ5IGFzc2lnbm1lbnRfc3RhdHVzLCBkZXZpY2VfY2F0ZWdvcnksIGFzc2lnbm1lbnRfdHlwZSwgaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UKCmBgYHtyfQpwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5ID0gZnVuY3Rpb24oY2F0KXsKICAKICAjIGRhdGEuYnkuY2F0ID0gZGYgJT4lIHNlbGVjdChwcm9qZWN0X2luc3RydWN0aW9uX0ZLLCBwcm9qZWN0X2luc3RydWN0aW9uX2xlbiwgcHJvamVjdF9pbnN0cnVjdGlvbl93b3JkQ291bnQsIHByb2plY3RfcmVxdWlyZWRfZmllbGRzLCBwcm9qZWN0X3NwZWNfbGVuZ3RoLCBwcm9qZWN0X2hhc19idXR0b24sICBwcm9qZWN0X2hhc19jaGVja2JveF9pbnB1dCwgcHJvamVjdF9oYXNfaW1hZ2UsIHByb2plY3RfaGFzX3JhZGlvX2lucHV0LCBwcm9qZWN0X2hhc19zdHJpbmdfaW5wdXQsIGNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjYXQpCiAgZGF0YS5ieS5jYXQgPSBkZiAlPiUgc2VsZWN0KHByb2plY3RfaW5zdHJ1Y3Rpb25fRkssIHByb2plY3RfaW5zdHJ1Y3Rpb25fbGVuLCBwcm9qZWN0X2luc3RydWN0aW9uX3dvcmRDb3VudCwgcHJvamVjdF9yZXF1aXJlZF9maWVsZHMsIHByb2plY3Rfc3BlY19sZW5ndGgsIGNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjYXQpCiAgCiAgZGF0YS5ieS5jYXQgPSBkYXRhLmJ5LmNhdCAlPiUgCiAgIyBwaXZvdF9sb25nZXIoY29scz1jKCdwcm9qZWN0X2luc3RydWN0aW9uX0ZLJywgJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fbGVuJywgJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fd29yZENvdW50JywgJ3Byb2plY3RfcmVxdWlyZWRfZmllbGRzJywgJ3Byb2plY3Rfc3BlY19sZW5ndGgnLCAncHJvamVjdF9oYXNfYnV0dG9uJywgICdwcm9qZWN0X2hhc19jaGVja2JveF9pbnB1dCcsICdwcm9qZWN0X2hhc19pbWFnZScsICdwcm9qZWN0X2hhc19yYWRpb19pbnB1dCcsICdwcm9qZWN0X2hhc19zdHJpbmdfaW5wdXQnKSwgbmFtZXNfdG8gPSAncGFyYW1ldGVyJykKICAgIHBpdm90X2xvbmdlcihjb2xzPWMoJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fRksnLCAncHJvamVjdF9pbnN0cnVjdGlvbl9sZW4nLCAncHJvamVjdF9pbnN0cnVjdGlvbl93b3JkQ291bnQnLCAncHJvamVjdF9yZXF1aXJlZF9maWVsZHMnLCAncHJvamVjdF9zcGVjX2xlbmd0aCcpLCBuYW1lc190byA9ICdwYXJhbWV0ZXInKQogIAogIHJldHVybihkYXRhLmJ5LmNhdCkKfQoKYGBgCgoKCmBgYHtyIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9MTB9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdhc3NpZ25tZW50X3N0YXR1cycpCgpwbHQgPSBkZjIgJT4lIGdncGxvdChhZXMoeD12YWx1ZSwgeT1jb21wbGV0aW9uLnRpbWUuaW4ubWludXRlcywgY29sb3I9YXNzaWdubWVudF9zdGF0dXMpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCBzdGF0dXMnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04LCBhbmdsZSA9IDMwKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9MTB9CmRmMiA9IHByZXBhcmUuZGYuYnkuY2F0ZWdvcnkoJ2RldmljZV9jYXRlZ29yeScpCgpwbHQgPSBkZjIgJT4lIGdncGxvdChhZXMoeD12YWx1ZSwgeT1jb21wbGV0aW9uLnRpbWUuaW4ubWludXRlcywgY29sb3I9ZGV2aWNlX2NhdGVnb3J5KSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBmYWNldF93cmFwKHZhcnMocGFyYW1ldGVyKSwgbnJvdz0xLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHhsYWIoJycpICsgeWxhYignY29tcGxldGlvbiB0aW1lIChpbiBtaW51dGUpJykgKyAKICBnZ3RpdGxlKCdwbG90IGJ5IGRldmljZSB0eXBlJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04LCBhbmdsZSA9IDMwKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9MTB9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdhc3NpZ25tZW50X3R5cGUnKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWFzc2lnbm1lbnRfdHlwZSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZmFjZXRfd3JhcCh2YXJzKHBhcmFtZXRlciksIG5yb3c9MSwgc2NhbGVzID0gImZyZWVfeCIpICsKICB4bGFiKCcnKSArIHlsYWIoJ2NvbXBsZXRpb24gdGltZSAoaW4gbWludXRlKScpICsgCiAgZ2d0aXRsZSgncGxvdCBieSBhc3NpZ25tZW50IHR5cGUnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGFuZ2xlID0gMzApLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKYGBge3IgZmlnLmhlaWdodD0zLjUsIGZpZy53aWR0aD0xMH0KCmRmMiA9IHByZXBhcmUuZGYuYnkuY2F0ZWdvcnkoJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UnKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPXByb2plY3RfaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgaW5zdHJ1Y3Rpb24gbGFuZ3VhZ2UnKSArIAogIHRoZW1lKAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGFuZ2xlID0gMzApLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScKICApCgpwbHQKYGBgCgoKCkNvbXBsZXRpb24gdGltZSBieSBwcm9qZWN0IGF0dHJpYnV0ZSAoaW5zdHJ1Y3Rpb25fRkssIGluc3RydWN0aW9uX2xhbmd1YWdlLCBpbnN0cnVjdGlvbl9sZW4sIGluc3RydWN0aW9uX3dvcmRDb3VudCwgcmVxdWlyZWRfZmllbGRzLCBzcGVjX2xlbmd0aCwgcHJvamVjdF9oYXNfYnV0dG9uLCAgcHJvamVjdF9oYXNfY2hlY2tib3hfaW5wdXQsIHByb2plY3RfaGFzX2ltYWdlLCBwcm9qZWN0X2hhc19yYWRpb19pbnB1dCwgcHJvamVjdF9oYXNfc3RyaW5nX2lucHV0KQoKRWFjaCBwbG90IGlzIGNhdGVnb3JpemVkIGJ5IGFzc2lnbm1lbnRfc3RhdHVzLCBkZXZpY2VfY2F0ZWdvcnksIGFzc2lnbm1lbnRfdHlwZSwgaW5zdHJ1Y3Rpb25fbGFuZ3VhZ2UKCmBgYHtyfQpwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5ID0gZnVuY3Rpb24oY2F0KXsKICAKICAjIGRhdGEuYnkuY2F0ID0gZGYgJT4lIHNlbGVjdChwcm9qZWN0X2luc3RydWN0aW9uX0ZLLCBwcm9qZWN0X2luc3RydWN0aW9uX2xlbiwgcHJvamVjdF9pbnN0cnVjdGlvbl93b3JkQ291bnQsIHByb2plY3RfcmVxdWlyZWRfZmllbGRzLCBwcm9qZWN0X3NwZWNfbGVuZ3RoLCBwcm9qZWN0X2hhc19idXR0b24sICBwcm9qZWN0X2hhc19jaGVja2JveF9pbnB1dCwgcHJvamVjdF9oYXNfaW1hZ2UsIHByb2plY3RfaGFzX3JhZGlvX2lucHV0LCBwcm9qZWN0X2hhc19zdHJpbmdfaW5wdXQsIGNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjYXQpCiAgZGF0YS5ieS5jYXQgPSBkZiAlPiUgc2VsZWN0KHByb2plY3RfaGFzX2J1dHRvbiwgIHByb2plY3RfaGFzX2NoZWNrYm94X2lucHV0LCBwcm9qZWN0X2hhc19pbWFnZSwgcHJvamVjdF9oYXNfcmFkaW9faW5wdXQsIHByb2plY3RfaGFzX3N0cmluZ19pbnB1dCwgY29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNhdCkKICAKICBkYXRhLmJ5LmNhdCA9IGRhdGEuYnkuY2F0ICU+JSAKICAjIHBpdm90X2xvbmdlcihjb2xzPWMoJ3Byb2plY3RfaW5zdHJ1Y3Rpb25fRksnLCAncHJvamVjdF9pbnN0cnVjdGlvbl9sZW4nLCAncHJvamVjdF9pbnN0cnVjdGlvbl93b3JkQ291bnQnLCAncHJvamVjdF9yZXF1aXJlZF9maWVsZHMnLCAncHJvamVjdF9zcGVjX2xlbmd0aCcsICdwcm9qZWN0X2hhc19idXR0b24nLCAgJ3Byb2plY3RfaGFzX2NoZWNrYm94X2lucHV0JywgJ3Byb2plY3RfaGFzX2ltYWdlJywgJ3Byb2plY3RfaGFzX3JhZGlvX2lucHV0JywgJ3Byb2plY3RfaGFzX3N0cmluZ19pbnB1dCcpLCBuYW1lc190byA9ICdwYXJhbWV0ZXInKQogICAgcGl2b3RfbG9uZ2VyKGNvbHM9YygncHJvamVjdF9oYXNfYnV0dG9uJywgICdwcm9qZWN0X2hhc19jaGVja2JveF9pbnB1dCcsICdwcm9qZWN0X2hhc19pbWFnZScsICdwcm9qZWN0X2hhc19yYWRpb19pbnB1dCcsICdwcm9qZWN0X2hhc19zdHJpbmdfaW5wdXQnKSwgbmFtZXNfdG8gPSAncGFyYW1ldGVyJykKICAKICByZXR1cm4oZGF0YS5ieS5jYXQpCn0KCmBgYAoKCgpgYGB7ciBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTEwfQoKZGYyID0gcHJlcGFyZS5kZi5ieS5jYXRlZ29yeSgnYXNzaWdubWVudF9zdGF0dXMnKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWFzc2lnbm1lbnRfc3RhdHVzKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBmYWNldF93cmFwKHZhcnMocGFyYW1ldGVyKSwgbnJvdz0xLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHhsYWIoJycpICsgeWxhYignY29tcGxldGlvbiB0aW1lIChpbiBtaW51dGUpJykgKyAKICBnZ3RpdGxlKCdwbG90IGJ5IGFzc2lnbm1lbnQgc3RhdHVzJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OCwgYW5nbGUgPSAzMCksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJwogICkKCnBsdApgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTEwfQpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdkZXZpY2VfY2F0ZWdvcnknKQoKcGx0ID0gZGYyICU+JSBnZ3Bsb3QoYWVzKHg9dmFsdWUsIHk9Y29tcGxldGlvbi50aW1lLmluLm1pbnV0ZXMsIGNvbG9yPWRldmljZV9jYXRlZ29yeSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZmFjZXRfd3JhcCh2YXJzKHBhcmFtZXRlciksIG5yb3c9MSwgc2NhbGVzID0gImZyZWVfeCIpICsKICB4bGFiKCcnKSArIHlsYWIoJ2NvbXBsZXRpb24gdGltZSAoaW4gbWludXRlKScpICsgCiAgZ2d0aXRsZSgncGxvdCBieSBkZXZpY2UgdHlwZScpICsgCiAgdGhlbWUoCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OCwgYW5nbGUgPSAzMCksCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJwogICkKCnBsdApgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTEwfQoKZGYyID0gcHJlcGFyZS5kZi5ieS5jYXRlZ29yeSgnYXNzaWdubWVudF90eXBlJykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PXZhbHVlLCB5PWNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjb2xvcj1hc3NpZ25tZW50X3R5cGUpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAodmFycyhwYXJhbWV0ZXIpLCBucm93PTEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeGxhYignJykgKyB5bGFiKCdjb21wbGV0aW9uIHRpbWUgKGluIG1pbnV0ZSknKSArIAogIGdndGl0bGUoJ3Bsb3QgYnkgYXNzaWdubWVudCB0eXBlJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04LCBhbmdsZSA9IDMwKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9MTB9CgpkZjIgPSBwcmVwYXJlLmRmLmJ5LmNhdGVnb3J5KCdwcm9qZWN0X2luc3RydWN0aW9uX2xhbmd1YWdlJykKCnBsdCA9IGRmMiAlPiUgZ2dwbG90KGFlcyh4PXZhbHVlLCB5PWNvbXBsZXRpb24udGltZS5pbi5taW51dGVzLCBjb2xvcj1wcm9qZWN0X2luc3RydWN0aW9uX2xhbmd1YWdlKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBmYWNldF93cmFwKHZhcnMocGFyYW1ldGVyKSwgbnJvdz0xLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHhsYWIoJycpICsgeWxhYignY29tcGxldGlvbiB0aW1lIChpbiBtaW51dGUpJykgKyAKICBnZ3RpdGxlKCdwbG90IGJ5IGluc3RydWN0aW9uIGxhbmd1YWdlJykgKyAKICB0aGVtZSgKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04LCBhbmdsZSA9IDMwKSwKICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nCiAgKQoKcGx0CmBgYA==